package com.winning.sjzc.common.utils;



import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Comments: json转换工具，目前仅支持obj到Json的转换
 * ProjectName: hrqms
 * Created by yunshuang·jiang on 2017/7/19 星期三
 * (C) Copyright 2017 www.winning.com.cn Inc.
 * All Rights Reserved.
 */
public class JSONUtils {
    /**
     * 将对象转换为json对象
     * @return JSONObject
     */
    public static JSON toJSON(Object obj) {
        if (obj == null) {
            return null;
        }
        // 以下类型不做处理
        if (obj.getClass().isAnnotation() || obj.getClass().isEnum()
                || obj.getClass().isInterface()) {
            return null;
        }
        // 判断是否为数字类型
        if (obj instanceof Number) {
            return null;
        }
        // 判断是否为基本类型或其封装类
        if (isPrimitive(obj)) {
            return null;
        }
        // 如果是字符串类型，判断是否本身即为Json类型
        if (obj instanceof String || obj instanceof StringBuilder
                || obj instanceof StringBuffer) {
            try {
                return JSONObject.fromObject(obj.toString());
            } catch (Exception e) {
                return null;
            }
        }
        // 判断Map
        if (obj instanceof Map) {
            return toJSON((Map)obj);
        }
        // 判断List
        if (obj instanceof Iterable) {
            return toJSONArray((Iterable)obj);
        }

        //=========== 上述情况都不是，则认为当前为pojo对象，迭代其成员变量，转换为JSON ===========//
        Set<Field> fieldSet = new HashSet<Field>(Arrays.asList(obj.getClass().getDeclaredFields()));
        for (Class c = obj.getClass(); !c.equals(Object.class); c = c.getSuperclass()) {
            // 合并父类成员变量
            Set<Field> superList = new HashSet<Field>(Arrays.asList(c.getDeclaredFields()));
            fieldSet.addAll(superList);
        }

        if (fieldSet.size() == 0) {
            return null;
        }

        JSONObject jsonObject = new JSONObject();
        for (Field field : fieldSet) {
            try {
                field.setAccessible(true);
                if (field.toString().contains("static")
                        || field.toString().contains("final")
                        || field.get(obj) == null) {
                    continue;
                }
                Object value = toJSON(field.get(obj));
                if (value != null) {
                    jsonObject.put(field.getName(), value);
                } else if (isPrimitive(field.get(obj))) {
                    jsonObject.put(field.getName(), field.get(obj));
                } else {
                    jsonObject.put(field.getName(), field.get(obj).toString());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return jsonObject;
    }

    /**
     * 将对象转换为json对象
     * @return JSONObject
     */
    public static JSONObject toJSON(Map obj) {
        if (obj == null) {
            return null;
        }
        JSONObject jobj = new JSONObject();
        for (Object key : obj.keySet()) {
            JSON value = toJSON(obj.get(key));
            if (value != null) {
                jobj.put(key.toString(), value);
            } else {
                jobj.put(key.toString(), obj.get(key));
            }
        }
        return jobj;
    }

    /**
     * 将对象转换为jsonArray对象
     * @return JSONObject
     */
    public static JSONArray toJSONArray(Iterable obj) {
        if (obj == null) {
            return null;
        }
        JSONArray array = new JSONArray();
        for (Object tmpObj : obj) {
            if (tmpObj == null) {
                continue;
            }
            JSON tmpJson = toJSON(tmpObj);
            if (tmpJson != null) {
                array.add(tmpJson);
            } else if (isPrimitive(tmpObj)) {
                array.add(tmpObj);
            } else {
                array.add(tmpObj.toString());
            }
        }
        return array;
    }

    /**
     * 判断对象是否是基本类型或其封装类
     * @param field 需要判断的对象
     * @return boolean
     */
    private static boolean isPrimitive(Object field) {
        return field.getClass().isPrimitive() ||
                field.getClass() == Boolean.class ||
                field.getClass() == Integer.class ||
                field.getClass() == Double.class ||
                field.getClass() == Float.class ||
                field.getClass() == Character.class ||
                field.getClass() == Long.class ||
                field.getClass() == Short.class ||
                field.getClass() == Byte.class;
    }
}
